package com.applet.shoppingcart.service.impl;

import com.applet.constant.MessageConstant;
import com.applet.context.AlibabaTTL;
import com.applet.dish.service.DishService;
import com.applet.dto.ShoppingCartDTO;
import com.applet.entity.Dish;
import com.applet.entity.Setmeal;
import com.applet.entity.ShoppingCart;
import com.applet.exception.ShoppingCartBusinessException;
import com.applet.setmeal.service.SetMealService;
import com.applet.shoppingcart.mapper.ShoppingCartMapper;
import com.applet.shoppingcart.service.ShoppingCartService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.Collator;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 购物车 serviceImpl
 */
@Slf4j
@Service
public class ShoppingCartServiceImpl implements ShoppingCartService {

    //购物车新增数据 默认数量1
    private static final Integer NEW_SHOPPING_CART_NUMBER = 1;

    @Resource
    private ShoppingCartMapper shoppingCartMapper;

    @Resource
    private DishService dishService;

    @Resource
    private SetMealService setMealService;



    /**
     * 购物车管理
     *          某一个用户 添加购物车数据
     * @param shoppingCartDTO
     */
    @Override
    public void addUserShoppingCartList(ShoppingCartDTO shoppingCartDTO) {
        // 1.数据检验
        if(Objects.nonNull(shoppingCartDTO.getDishId()) && Objects.nonNull(shoppingCartDTO.getSetmealId())){
            //dishId 和 setmealId同时存在 抛出异常
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_PARAMS_ERROR);
        }

        // 2.取出token中解析出来的用户id
        Long userId = Long.valueOf(AlibabaTTL.threadLocalGet().toString());

        // 3.构建查询参数对象
        ShoppingCart paramShopCart = ShoppingCart.builder().userId(userId).build();

        // 4.先查询，判断是查询菜品还是套餐
        if(Objects.nonNull(shoppingCartDTO.getDishId())){
            // SQL: select * from shopping_cart where user_id = ? and dish_id = ? and dish_flavor = ?
            // dishId不为空 查菜品
            // 根据 用户id和菜品id查询购物车，判断当前用户是否在购物车中添加了该菜品
            paramShopCart.setDishId(shoppingCartDTO.getDishId());
            // 菜品口味数据排序
            if(StringUtils.hasLength(shoppingCartDTO.getDishFlavor())){
                // 取出口味数据，用","切割
                String[] flavors = shoppingCartDTO.getDishFlavor().split(",");
                // 判断
                if(flavors.length > 1){
                    List<String> flavorList = Stream.of(flavors).filter(StringUtils::hasLength).collect(Collectors.toList());
                    // 汉字排序
                    Collections.sort(flavorList, new Comparator<String>() {
                        @Override
                        public int compare(String s1, String s2) {
                            Collator instance = Collator.getInstance();
                            return instance.compare(s1, s2);
                        }
                    });
                    String sortStr = flavorList.stream().collect(Collectors.joining(","));
                    //System.out.println("排序后:" + sortStr);
                    paramShopCart.setDishFlavor(sortStr);
                } else {
                    paramShopCart.setDishFlavor(shoppingCartDTO.getDishFlavor());
                }
            }
        } else {
            // SQL: select * from shopping_cart where user_id = ? and setmeal_id = ?
            // 否则，查套餐
            // 根据 用户id和菜品id查询购物车，判断当前用户是否在购物车中添加了该套餐
            paramShopCart.setSetmealId(shoppingCartDTO.getSetmealId());
        }

        // 5.查询是否该菜品或套餐已存在购物车中
        ShoppingCart oldShoppingCart = shoppingCartMapper.selectUserShopCart(paramShopCart);



        // 6.判断用户添加的 菜品/套餐 是否已经存在购物车了
        if(Objects.isNull(oldShoppingCart)){
            // 不存在，新增操作
            ShoppingCart newShoppingCart = null;

            // 判断是新增菜品，还是套餐  到购物车
            if(Objects.nonNull(shoppingCartDTO.getDishId())){
                // dishId不为空 则为添加菜品到购物车
                // 查询菜品信息
                Dish dish = dishService.selectDishById(shoppingCartDTO.getDishId());
                // 构建菜品的购物车数据
                newShoppingCart = ShoppingCart.builder().name(dish.getName()).image(dish.getImage()).userId(userId).dishId(shoppingCartDTO.getDishId()).number(NEW_SHOPPING_CART_NUMBER).amount(dish.getPrice()).createTime(LocalDateTime.now()).build();
                // 口味数据先排序再设置
                if(StringUtils.hasLength(shoppingCartDTO.getDishFlavor())){
                    String[] flavors = shoppingCartDTO.getDishFlavor().split(",");
                    // 判断口味数据一个还是多个
                    if(flavors.length > 1){
                        List<String> flavorList = Stream.of(flavors).filter(StringUtils::hasLength).collect(Collectors.toList());
                        // 汉字排序
                        Collections.sort(flavorList, new Comparator<String>() {
                            @Override
                            public int compare(String s1, String s2) {
                                Collator instance = Collator.getInstance();
                                return instance.compare(s1, s2);
                            }
                        });
                        String sortStr = flavorList.stream().collect(Collectors.joining(","));
                        //System.out.println("排序后:" + sortStr);
                        newShoppingCart.setDishFlavor(sortStr);
                    } else {
                        newShoppingCart.setDishFlavor(shoppingCartDTO.getDishFlavor());
                    }
                }
            } else {
                // 否则，添加的是套餐到购物车
                // 查询套餐数据
                Setmeal setmeal = setMealService.selectSetMealById(shoppingCartDTO.getSetmealId());
                // 构建套餐的购物车数据
                newShoppingCart = ShoppingCart.builder().name(setmeal.getName()).image(setmeal.getImage()).userId(userId).setmealId(setmeal.getId()).number(NEW_SHOPPING_CART_NUMBER).amount(setmeal.getPrice()).createTime(LocalDateTime.now()).build();
            }

            //添加购物车
            Integer count = shoppingCartMapper.insert(newShoppingCart);

        } else {
            // 存在，修改数量操作
            oldShoppingCart.setNumber(oldShoppingCart.getNumber() + 1);
            Integer userShopCartCount = shoppingCartMapper.updateUserShopCatById(oldShoppingCart);
        }

    }



    /**
     * 购物车管理
     *          根据userId查询购物车数据
     * @param userId
     */
    @Override
    public List<ShoppingCart> selectUserShopCart(Long userId) {
        //判断前端,有没有传递userId
        if(Objects.isNull(userId)){
            //没有传，则
            userId = Long.valueOf(AlibabaTTL.threadLocalGet().toString());
            log.info("查 - threadLocal中取出用户id: {}", userId);
        }
        return shoppingCartMapper.selectUserShopCartListByUserId(userId);
    }



    /**
     * 购物车管理
     *           根据userId清空购物车数据
     * @param userId
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void deleteUserShopCart(Long userId) {
        //判断前端,有没有传递userId
        if(Objects.isNull(userId)){
            //没有传，则
            userId = Long.valueOf(AlibabaTTL.threadLocalGet().toString());
            log.info("清空 - threadLocal中取出用户id: {}", userId);
        }
        Integer count = shoppingCartMapper.deleteUserShopCartByUserId(userId);
        log.info("用户id: {},清空购物车: {}条数据", userId, count);
    }



    /**
     * 购物车管理
     *         减少用户 菜品/套餐 的数量
     * @param shoppingCartDTO
     */
    @Override
    public void deleteUserShopCartCopies(ShoppingCartDTO shoppingCartDTO) {
        // 1.数据检验
        if(Objects.nonNull(shoppingCartDTO.getDishId()) && Objects.nonNull(shoppingCartDTO.getSetmealId())){
            //dishId 和 setmealId同时存在 抛出异常
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_PARAMS_ERROR);
        }

        // 2.取出token中解析出来的用户id
        Long userId = Long.valueOf(AlibabaTTL.threadLocalGet().toString());

        // 3.构建查询参数对象
        ShoppingCart shoppingCart = ShoppingCart.builder().userId(userId).build();

        // 4.判断是查询菜品还是套餐
        if(Objects.nonNull(shoppingCartDTO.getDishId())){
            // SQL: select * from shopping_cart where user_id = ? and dish_id = ? and dish_flavor = ?
            //dishId不为空 则查询菜品
            shoppingCart.setDishId(shoppingCartDTO.getDishId());

            //判断有没有口味数据
            if(StringUtils.hasLength(shoppingCartDTO.getDishFlavor())){
                // 口味数据 按照","切割
                String[] strings = shoppingCartDTO.getDishFlavor().split(",");
                // 判断是否有多个口味数据
                if(strings.length > 1){
                    List<String> flavorList = Stream.of(strings).filter(StringUtils::hasLength).collect(Collectors.toList());
                    Collections.sort(flavorList, new Comparator<String>() {
                        @Override
                        public int compare(String s1, String s2) {
                            Collator instance = Collator.getInstance();
                            return instance.compare(s1, s2);
                        }
                    });
                    String sortStr = flavorList.stream().collect(Collectors.joining(","));
                    //System.out.println("排序后:" + sortStr);
                    shoppingCart.setDishFlavor(sortStr);
                } else {
                    shoppingCart.setDishFlavor(shoppingCartDTO.getDishFlavor());
                }
            }

        } else {
            // SQL: select * from shopping_cart where user_id = ? and setmeal_id = ?
            //否则，查询套餐
            shoppingCart.setSetmealId(shoppingCartDTO.getSetmealId());
        }

        // 5.查询这个菜品/套餐的购物车记录
        ShoppingCart oldShoppingCart = shoppingCartMapper.selectUserShopCart(shoppingCart);

        // 6.判断是否有数据，没数据不处理
        if(Objects.nonNull(oldShoppingCart)){
            // 7.获取当前菜品/套餐 在购物车的下单的份数
            Integer number = oldShoppingCart.getNumber();
            // 8.判断 数量为 1 则直接删除，不为 1 则 (number-1)
            if(1 == number) {
                //直接删除
                Integer count = shoppingCartMapper.deleteUserShopCart(shoppingCart);
            } else {
                // 数量-1
                oldShoppingCart.setNumber(oldShoppingCart.getNumber() - 1);
                Integer count = shoppingCartMapper.updateUserShopCatById(oldShoppingCart);
            }
        }

    }



    /**
     * 购物车管理
     *          添加单条购物车
     * @param shoppingCart
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void addUserShoppingCart(ShoppingCart shoppingCart) {
        shoppingCartMapper.insert(shoppingCart);
    }


}
